using System;

using CMS.PortalControls;
using CMS.GlobalHelper;
using CMS.CMSHelper;
using CMS.PortalEngine;

public partial class CMSWebParts_General_MobileDeviceRedirection : CMSAbstractWebPart
{
    #region "Constants"

    private const string SETTINGS_DEVICE_AUTOMATIC = "automatic";
    private const string SETTINGS_DEVICE_SMALL = "small";
    private const string SETTINGS_DEVICE_LARGE = "large";

    #endregion


    #region "Properties"

    /// <summary>
    /// Small device redirection URL.
    /// </summary>
    public string SmallDeviceRedirectionURL
    {
        get
        {
            return ValidationHelper.GetString(GetValue("SmallDeviceRedirectionURL"), string.Empty);
        }
        set
        {
            SetValue("SmallDeviceRedirectionURL", value);
        }
    }


    /// <summary>
    /// Large device redirection URL.
    /// </summary>
    public string LargeDeviceRedirectionURL
    {
        get
        {
            return ValidationHelper.GetString(GetValue("LargeDeviceRedirectionURL"), string.Empty);
        }
        set
        {
            SetValue("LargeDeviceRedirectionURL", value);
        }
    }


    /// <summary>
    /// Redirect iPhone.
    /// </summary>
    public string RedirectIPhone
    {
        get
        {
            return ValidationHelper.GetString(GetValue("RedirectIPhone"), string.Empty);
        }
        set
        {
            SetValue("RedirectIPhone", value);
        }
    }


    /// <summary>
    /// Redirect Nokia.
    /// </summary>
    public string RedirectNokia
    {
        get
        {
            return ValidationHelper.GetString(GetValue("RedirectNokia"), string.Empty);
        }
        set
        {
            SetValue("RedirectNokia", value);
        }
    }


    /// <summary>
    /// Redirect BlackBerry.
    /// </summary>
    public string RedirectBlackBerry
    {
        get
        {
            return ValidationHelper.GetString(GetValue("RedirectBlackBerry"), string.Empty);
        }
        set
        {
            SetValue("RedirectBlackBerry", value);
        }
    }


    /// <summary>
    /// Redirect iPad.
    /// </summary>
    public string RedirectIPad
    {
        get
        {
            return ValidationHelper.GetString(GetValue("RedirectIPad"), string.Empty);
        }
        set
        {
            SetValue("RedirectIPad", value);
        }
    }


    /// <summary>
    /// Redirect Android.
    /// </summary>
    public string RedirectAndroid
    {
        get
        {
            return ValidationHelper.GetString(GetValue("RedirectAndroid"), string.Empty);
        }
        set
        {
            SetValue("RedirectAndroid", value);
        }
    }


    /// <summary>
    /// Always redirect.
    /// </summary>
    public bool AlwaysRedirect
    {
        get
        {
            return ValidationHelper.GetBoolean(GetValue("AlwaysRedirect"), false);
        }
        set
        {
            SetValue("AlwaysRedirect", value);
        }
    }


    /// <summary>
    /// Other small devices (User agent).
    /// </summary>
    public string OtherSmallDevices
    {
        get
        {
            return ValidationHelper.GetString(GetValue("OtherSmallDevices"), string.Empty);
        }
        set
        {
            SetValue("OtherSmallDevices", value);
        }
    }


    /// <summary>
    /// Other large devices (User agent).
    /// </summary>
    public string OtherLargeDevices
    {
        get
        {
            return ValidationHelper.GetString(GetValue("OtherLargeDevices"), string.Empty);
        }
        set
        {
            SetValue("OtherLargeDevices", value);
        }
    }

    #endregion


    #region "Webpart methods"

    /// <summary>
    /// Content loaded event handler.
    /// </summary>
    public override void OnContentLoaded()
    {
        base.OnContentLoaded();
        SetupControl();
    }


    /// <summary>
    /// Initializes the control properties.
    /// </summary>
    protected void SetupControl()
    {
        if (!StopProcessing)
        {
            // Trim blank characters
            string rawSmallDeviceURL = SmallDeviceRedirectionURL.Trim();
            string rawLargeDeviceURL = LargeDeviceRedirectionURL.Trim();

            // Get redirect cookie
            string redirected = CookieHelper.GetValue("CMSMobileRedirected");

            if ((AlwaysRedirect || String.IsNullOrEmpty(redirected)) && (CMSContext.ViewMode == ViewModeEnum.LiveSite))
            {
                string redirectUrl = null;

                // Get user agent name or user agent string
                string userAgent = BrowserHelper.GetUserAgent();

                if (!string.IsNullOrEmpty(userAgent))
                {
                    UserAgentEnum userAgentEnum = GetUserAgentName(userAgent);
                    string redirectSettings = null;
                    switch (userAgentEnum)
                    {
                        case UserAgentEnum.BlackBerry:
                            redirectSettings = RedirectBlackBerry;
                            break;

                        case UserAgentEnum.IPhone:
                            redirectSettings = RedirectIPhone;
                            break;

                        case UserAgentEnum.IPad:
                            redirectSettings = RedirectIPad;
                            break;

                        case UserAgentEnum.Nokia:
                            redirectSettings = RedirectNokia;
                            break;

                        case UserAgentEnum.Android:
                            redirectSettings = RedirectAndroid;
                            break;
                    }

                    if (redirectSettings != null)
                    {
                        redirectUrl = GetRedirectUrl(redirectSettings, userAgent, userAgentEnum, rawSmallDeviceURL, rawLargeDeviceURL);
                    }
                    else
                    {
                        redirectUrl = CheckUsersRedirection(userAgent, rawSmallDeviceURL, rawLargeDeviceURL);
                    }
                }

                // Check if some address is specified
                if (!string.IsNullOrEmpty(redirectUrl))
                {
                    string newURL = URLHelper.ResolveUrl(redirectUrl);

                    // If current URL is same as set, no redirection is done
                    if ((URLHelper.CurrentURL != newURL) && (URLHelper.GetAbsoluteUrl(URLHelper.CurrentURL) != newURL))
                    {
                        // Set redirected cookie
                        CookieHelper.SetValue("CMSMobileRedirected", "true", DateTimeHelper.ZERO_TIME);
                        URLHelper.ResponseRedirect(newURL);
                    }
                }
            }
        }
    }


    /// <summary>
    /// Returns redirect url for specified user agent and redirection settings.
    /// </summary>
    protected string GetRedirectUrl(string redirectSettings, string userAgent, UserAgentEnum userAgentEnum, string smallUrl, string largeUrl)
    {
        switch (redirectSettings)
        {
            case SETTINGS_DEVICE_AUTOMATIC:
                string url = CheckUsersRedirection(userAgent, smallUrl, largeUrl);

                if (!string.IsNullOrEmpty(url))
                {
                    return url;
                }
                else
                {
                    switch (userAgentEnum)
                    {
                        case UserAgentEnum.BlackBerry:
                            return smallUrl;

                        case UserAgentEnum.IPhone:
                            return largeUrl;

                        case UserAgentEnum.IPad:
                            return largeUrl;

                        case UserAgentEnum.Nokia:
                            return largeUrl;

                        case UserAgentEnum.Android:
                            return largeUrl;

                        default:
                            return smallUrl;
                    }
                }

            case SETTINGS_DEVICE_SMALL:
                return smallUrl;

            case SETTINGS_DEVICE_LARGE:
                return largeUrl;

            default:
                return string.Empty;
        }
    }


    /// <summary>
    /// Returns user agent enum for given user agent string.
    /// </summary>
    protected UserAgentEnum GetUserAgentName(string userAgent)
    {
        userAgent = userAgent.ToLower();
        if (userAgent.Contains(UserAgentEnum.BlackBerry.ToString().ToLower()))
        {
            return UserAgentEnum.BlackBerry;
        }
        else if (userAgent.Contains(UserAgentEnum.IPhone.ToString().ToLower()))
        {
            return UserAgentEnum.IPhone;
        }
        else if (userAgent.Contains(UserAgentEnum.IPad.ToString().ToLower()))
        {
            return UserAgentEnum.IPad;
        }
        else if (userAgent.Contains(UserAgentEnum.Nokia.ToString().ToLower()))
        {
            return UserAgentEnum.Nokia;
        }
        else if (userAgent.Contains(UserAgentEnum.Android.ToString().ToLower()))
        {
            return UserAgentEnum.Android;
        }

        return UserAgentEnum.Unknown;
    }


    /// <summary>
    /// Initializes the control properties.
    /// </summary>
    protected string CheckUsersRedirection(string userAgent, string smallUrl, string largeUrl)
    {
        // Split user specified user agents
        string[] largeDevices = OtherLargeDevices.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);
        string[] smallDevices = OtherSmallDevices.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);

        userAgent = userAgent.ToLower();

        // Check large devices
        if (largeDevices.Length > 0)
        {
            // Check all specified devices for match
            foreach (string t in largeDevices)
            {
                if (userAgent.Contains(t.ToLower()))
                {
                    return largeUrl;
                }
            }
        }

        // Check small devices
        if (smallDevices.Length > 0)
        {
            // Check all specified devices for match
            foreach (string t in smallDevices)
            {
                if (userAgent.Contains(t.ToLower()))
                {
                    return smallUrl;
                }
            }
        }

        // Check if visitor use mobile device
        if (BrowserHelper.IsMobileDevice())
        {
            return smallUrl;
        }

        return string.Empty;
    }

    #endregion
}